<?php
/**
 * QQAuth_API
 * 用于定义向远程服务器请求的各种接口。
 * 
 * 
 * 
 * 
 */
class QQAuth_API
{
	/**
	 * 主要属于向远程服务器拉取数据或者提交数据用
	 * 
	 * @param string $interface 接口名，在config/config.php里配置
	 * @param array	$params 请求参数
	 * 
	 * @return 远程服务器的响应
	 * 例：
	 * Get
	 * 外部调用QQAuth::process('get_user_info');
	 * 对应的API请求端地址在config/config.php $GLOBALS['QQAuth_Grant_Url_Map']的键值为$interface，url末尾不要带"?".
	 * 
	 * Post
	 * 外部调用QQAuth::process('add_share', array('title' => 'Baidu', 'url' => 'http://baidu.com' ));
	 * 对应的API请求端地址在config/config.php $GLOBALS['QQAuth_Grant_Url_Map']的键值为$interface，url末尾不要带"?".
	 * 
	 * 
	 * 当不成功则抛出QQAuth_Exception异常。
	 * 
	 * 
	 */
	public static function process( $interface, $params = array() )
	{
		$global_map_key = 'QQAuth_Grant_Url_Map';
		if ( isset( $GLOBALS[$global_map_key] ) )
		{
			if( array_key_exists($interface, $GLOBALS[$global_map_key]) )
			{
				$url = $GLOBALS[$global_map_key][$interface]['url'];// 获取API请求地址	
				$method = $GLOBALS[$global_map_key][$interface]['method'];// 获取请求方式
			} 
			else
			{
				throw new QQAuth_Exception("Interface '$interface' not defined, check config/config.php", 'i0001');
			}
		}
		else 
		{
			throw new QQAuth_Exception("Global variable '$global_map_key' not defined, check config/config.php", 'i0001');
		}
		
			
		// 合并元参数
		$params = self::getMetaParams() + $params;
			

		return self::doRequest( $url, $params, $method );
	}
	
	
	/**
	 * 发起请求的方法，统一发送接口，并处理不成功的响应（抛出异常）
	 * 
	 * @return $ret array 服务器端响应
	 */
	public static function doRequest( $url, $data , $method='post' )
	{
		if ($method == 'post')
		{ // 适用于提交数据到远程服务器
			// 发起请求
			$ret = QQAuth_Util::doPost( $url, $data ); 
		}
		else
		{ // 适用于从远程服务器拉取数据
			// 构造url参数
			$url = $url . '?' . QQAuth_Util::composeParams( $data );
			
			// 发起请求
			$info = QQAuth_Util::doGet( $url );
			
			// 解析json
			$ret = json_decode($info, true);
		}
		
		if ( is_null($ret) || $ret['ret'] > 0 )
		{
			$msg 	= "Error occured when requesting: $url\n";
			$msg   .= "with params:" .print_r($data, true);
			$msg   .= "Response: " . print_r($info, true);
			// 抛出异常
			throw new QQAuth_Exception($msg, $ret['ret']);
		}
		
		return $ret;
	}
	

	/**
	 * 获取元参数数组
	 * 包含 access_token, oauth_consumer_key, openid, format
	 * 详情参考
	 * http://wiki.open.qq.com/wiki/%E3%80%90QQ%E7%99%BB%E5%BD%95%E3%80%91OpenAPI2.0%E8%B0%83%E7%94%A8%E8%AF%B4%E6%98%8E#2._.E8.B0.83.E7.94.A8OpenAPI.E6.8E.A5.E5.8F.A3
	 */
	public static function getMetaParams()
	{
		return array(
			'access_token' 			=> $_SESSION['QQAUTH_ACCESS_TOKEN'],
			'oauth_consumer_key' 	=> QQAUTH_APP_ID,
			'openid' 				=> $_SESSION['QQAUTH_OPENID'],
			'format'				=> 'json'
		);
	}
	
	/***************************************************************
	 * 下面的方法已经过时。
	 * *************************************************************
	 */ 
	/**
	 * 获取请求接口的URL
	 * @param $type string 接口类型
	 * 
	 * @return $url string 接口URL
	 * 
	 * 例：
	 * $type = 'userinfo'; 
	 * 返回宏QQAUTH_API_USERINFO_URL的值，该宏定义在config/config.php
	 * 
	 */
		
	public static function getAPIUrl( $type )
	{
		$constant_name = 'QQAUTH_API_' . strtoupper($type) . '_URL';
		return constant($constant_name);
	}
	
	/**
	 * 魔术方法，用于处理以get,和post开头的未定义的函数，主要属于向远程服务器拉取数据或者提交数据用
	 * 
	 * 例：
	 * Get
	 * 外部调用$api->getUserInfo().
	 * 对应的API请求端地址在config/config.php 为 QQAUTH_API_[方法名除get或post的部分的大写]_URL，本例为QQAUTH_API_USERINFO_URL注意，url末尾不要带"?".
	 * 
	 * Post
	 * 外部调用$api->postBlog( $data ).
	 * $data的参数可参考http://wiki.open.qq.com/wiki/%E3%80%90QQ%E7%99%BB%E5%BD%95%E3%80%91add_one_blog
	 * 对应的API请求端地址在config/config.php 为 QQAUTH_API_[方法名除get或post的部分的大写]_URL，本例为QQAUTH_API_USERINFO_URL注意，url末尾不要带"?".
	 * 
	 * @return 远程服务器的响应
	 * 
	 * 当不成功则抛出QQAuth_Exception异常。
	 * 
	 * 
	 */
	public function __call( $function,  $args = array())
	{ 
		if ( QQAuth_Util::startsWith( $function, 'get' ) )
		{
			$method = 'get';
			// 获取类型
			$type = strtolower(substr( $function, 3 ));
		}
		else
		{
			$method = 'post';
			// 获取类型
			$type = strtolower(substr( $function, 4 ));
		}
		// 获取API请求地址
		$url = self::getAPIUrl( $type );
			
		// 获取元参数
		$params = self::getMetaParams();
			
		// 
		if (isset($args[0]))
		{
			$params = $params + $args[0];
		}

		return self::doRequest( $url, $params, $method );
	}
	/**
	 * 添加博文的方法
	 * 
	 * @param $data array 博文的数据
	 * 
	 * $data = array(
	 * 			'title' => $title,
	 * 			'content' => $content
	 * 			);
	 * 
	 * @return $ret array 远程服务器端响应
	 */
	public static function processAddBlog( $data )
	{
		// 博文的接口地址，在config/config.php中定义
		$url  = self::getAPIUrl('blog');
	    
	    // 获取元参数
	    $params = self::getMetaParams();
	    
	    // 合并参数数组
	    $params = array_merge($params, $data);
	    
		// 发起请求
	    $ret = self::doRequest( $url, $params );
	    return $ret;	
	}
	
	/**
	 * 获取用户信息的方法
	 * 
	 * @return $ret array 远程服务器端响应
	 */
	public static function processGetUserInfo(  )
	{
		// 用户信息的接口地址，在config/config.php中定义
	    $url  = self::getAPIUrl('userinfo');
	    
	    // 获取元参数
	    $params = self::getMetaParams();
	
		// 发起请求
	    $ret = self::doRequest( $url, $params, 'get' );
	    return $ret;	
	}
	
	
	/**
	 * 获取用户相册列表的方法
	 * 
	 * @return $ret array 远程服务器端响应
	 */
	public static function processGetAlbumList(  )
	{
		// 用户相册列表的接口地址，在config/config.php中定义
	    $url  = self::getAPIUrl('albumlist');
	    
	    // 获取元参数
	    $params = self::getMetaParams();
	
		// 发起请求
	    $ret = self::doRequest( $url, $params, 'get' );
	    return $ret;	
	}
}